/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package p2a;


import java.util.Vector;

/**
 *
 * @author Chaker
 */



public class RulesAnalyse {
    public static final int NOANOMALY=1;
    public static final int REDUNDANCY=2;
    public static final int GENERALIZATION=3;
    public static final int CORRELATION=4;
    public static final int SHADOWING=5;
    
    public static Vector<RuleAux> ToRulesAux(Vector<Rule> rules)
    {
        Vector<RuleAux> rulesAux=new Vector<RuleAux>(rules.size());
        for (Rule rule:rules)
        {
            rulesAux.add(new RuleAux(rule));
        }
        return rulesAux;
    }  
    public static boolean ipInclude(String ip1, String ip2)
    {
        String[] ip1_values = ip1.split("\\.");
        String[] ip2_values = ip2.split("\\.");
        boolean test=true;
        for (int i=0; i<4; i++)
        {
            if (!(ip1_values[i].equals(ip2_values[i]) || ip2_values[i].equals("*")))
                test=false;
        }
        return test;
    }
    private static boolean includes(int field, String value1, String value2)
    {
        switch (field)
        {
            case RuleAux.ACTION: return false;
            case RuleAux.DEST_IP: return ipInclude(value1,value2);
            case RuleAux.DEST_PORT: return (!value1.equals(value2) && value2.equals("*"));
            case RuleAux.SRC_IP: return ipInclude(value1,value2);
            case RuleAux.SRC_PORT: return (!value1.equals(value2) && value2.equals("*"));
            case RuleAux.PROTOCOL: return false;
            default : return false;
        }
    }
    static int getAnomaly(RuleAux Rx, RuleAux Ry)
    {
        int a=0,b=0,c=0,field=RuleAux.PROTOCOL, anomaly=NOANOMALY, total=RuleAux.FIELDS_NB-1;
        while (field < RuleAux.ACTION)
        {
            if (Rx.getParameter(field).equalsIgnoreCase(Ry.getParameter(field)))
            {
                c++;
            }
            else if (includes(field,Ry.getParameter(field), Rx.getParameter(field)))
            {
                a++;
            }
            else if (includes(field,Rx.getParameter(field), Ry.getParameter(field)))
            {
                b++;
            }
            field++;
        }
        if (b+c==total)
        {
            if (Rx.getAction().equalsIgnoreCase(Ry.getAction()))
                anomaly = REDUNDANCY;
            else
                anomaly = SHADOWING;
        }
        else if (a+c==total)
        {
            if (!Rx.getAction().equalsIgnoreCase(Ry.getAction()))
            {
                anomaly = GENERALIZATION;
            }
        }
        else if (a+b+c==total)
        {
            if (!Rx.getAction().equalsIgnoreCase(Ry.getAction()))
                anomaly = CORRELATION;
        }
        return anomaly;
    }
    public static Vector<String> Test(Vector<RuleAux> rules)
    {
        Vector<String> result = new Vector();
        int anomaly;
        RuleAux Rx,Ry;
        for (int i=1; i<rules.size(); i++)
        {
            for (int j=0; j<i; j++)
            {
                Rx = rules.get(i);
                Ry = rules.get(j);
                anomaly = getAnomaly(Rx, Ry);
                switch (anomaly)
                {
                    case REDUNDANCY : result.add("Rule "+Rx.getOrder()+" is redendant to Rule "+Ry.getOrder());//System.out.println(Rx.getOrder()+" is redendant to "+Ry.getOrder());
                            break;
                    case SHADOWING : result.add("Rule "+Rx.getOrder()+" is shadowed by Rule "+Ry.getOrder());//System.out.println(Rx.getOrder()+" is shadowed by "+Ry.getOrder());
                            break;
                    case GENERALIZATION :result.add("Rule "+Rx.getOrder()+" is a generalization of Rule "+Ry.getOrder());// System.out.println(Rx.getOrder()+" is a generalization of "+Ry.getOrder());
                            break;
                    case CORRELATION : result.add("Rule "+Rx.getOrder()+" is correlated to Rule "+Ry.getOrder());//System.out.println(Rx.getOrder()+" is correlated to "+Ry.getOrder());
                }
            }
        }
        
        return result;
    }
}


